// Copyright 2023 Ant Group Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "yacl/crypto/ecc/curve_meta.h"

#include <map>

#include "absl/strings/ascii.h"

#include "yacl/base/exception.h"

namespace yacl::crypto {

// The following literals are automatically generated by tools, please do not
// modify.
// How to refresh this table
//   git clone git@github.com:usafchn/std-curves.git
//   python convert.py
std::vector<CurveMeta> kPredefinedCurves = {
    // Category: SECG
    // SEC 2: Recommended Elliptic Curve Domain Parameters version 2.0  January
    // 27, 2010
    // A randomly generated curve.
    // [SEC2v1](https://www.secg.org/SEC2-Ver-1.0.pdf) states 'E was chosen
    // verifiably at random as specified in ANSI X9.62 [1] from the seed'.
    {"secp112r1",
     {"wap-wsg-idm-ecid-wtls6"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     56},
    // A randomly generated curve.
    // [SEC2v1](https://www.secg.org/SEC2-Ver-1.0.pdf) states 'E was chosen
    // verifiably at random as specified in ANSI X9.62 [1] from the seed'.
    {"secp112r2", {}, CurveForm::Weierstrass, FieldType::Prime, 56},
    // A randomly generated curve.
    // [SEC2v1](https://www.secg.org/SEC2-Ver-1.0.pdf) states 'E was chosen
    // verifiably at random as specified in ANSI X9.62 [1] from the seed'.
    {"secp128r1", {}, CurveForm::Weierstrass, FieldType::Prime, 64},
    // A randomly generated curve.
    // [SEC2v1](https://www.secg.org/SEC2-Ver-1.0.pdf) states 'E was chosen
    // verifiably at random as specified in ANSI X9.62 [1] from the seed'.
    {"secp128r2", {}, CurveForm::Weierstrass, FieldType::Prime, 64},
    // A Koblitz curve.
    {"secp160k1", {"ansip160k1"}, CurveForm::Weierstrass, FieldType::Prime, 80},
    // A randomly generated curve.
    // [SEC2v1](https://www.secg.org/SEC2-Ver-1.0.pdf) states 'E was chosen
    // verifiably at random as specified in ANSI X9.62 [1] from the seed'.
    {"secp160r1",
     {"wap-wsg-idm-ecid-wtls7", "ansip160r1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     80},
    // A randomly generated curve.
    // [SEC2v1](https://www.secg.org/SEC2-Ver-1.0.pdf) states 'E was chosen
    // verifiably at random as specified in ANSI X9.62 [1] from the seed'.
    {"secp160r2", {"ansip160r2"}, CurveForm::Weierstrass, FieldType::Prime, 80},
    // A Koblitz curve.
    {"secp192k1", {"ansip192k1"}, CurveForm::Weierstrass, FieldType::Prime, 96},
    // A randomly generated curve.
    // [SEC2v1](https://www.secg.org/SEC2-Ver-1.0.pdf) states 'E was chosen
    // verifiably at random as specified in ANSI X9.62 [1] from the seed'.
    {"secp192r1",
     {"P-192", "prime192v1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     96},
    // A Koblitz curve.
    {"secp224k1",
     {"ansip224k1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     112},
    // A randomly generated curve.
    // [SEC2v1](https://www.secg.org/SEC2-Ver-1.0.pdf) states 'E was chosen
    // verifiably at random as specified in ANSI X9.62 [1] from the seed'.
    {"secp224r1",
     {"P-224", "wap-wsg-idm-ecid-wtls12", "ansip224r1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     112},
    // A Koblitz curve.
    {"secp256k1",
     {"ansip256k1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     128},
    // A randomly generated curve.
    // [SEC2v1](https://www.secg.org/SEC2-Ver-1.0.pdf) states 'E was chosen
    // verifiably at random as specified in ANSI X9.62 [1] from the seed'.
    {"secp256r1",
     {"P-256", "prime256v1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     128},
    {"secp384r1",
     {"P-384", "ansip384r1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     192},
    {"secp521r1",
     {"P-521", "ansip521r1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     260},
    {"sect113r1",
     {"wap-wsg-idm-ecid-wtls4"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     56},
    {"sect113r2", {}, CurveForm::Weierstrass, FieldType::Binary, 56},
    {"sect131r1", {}, CurveForm::Weierstrass, FieldType::Binary, 65},
    {"sect131r2", {}, CurveForm::Weierstrass, FieldType::Binary, 65},
    {"sect163k1",
     {"K-163", "ansit163k1", "wap-wsg-idm-ecid-wtls3"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     81},
    // A randomly generated curve, using the X9.62 method. 'However for
    // historical reasons the method used to generate E from S differs slightly
    // from the method described in ANSI X9.62 [X9.62]. Specifically the
    // coefficient b produced from S is the reverse of the coefficient that
    // would have been produced by the method described in ANSI X9.62.'
    {"sect163r1",
     {"ansit163r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     81},
    // A randomly generated curve. 'E was selected from S as specified in ANSI
    // X9.62 [X9.62] in normal basis representation and converted into
    // polynomial basis representation.'
    {"sect163r2",
     {"B-163", "ansit163r2"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     81},
    {"sect193r1",
     {"ansit193r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     96},
    {"sect193r2",
     {"ansit193r2"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     96},
    {"sect233k1",
     {"K-233", "wap-wsg-idm-ecid-wtls10", "ansit233k1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     116},
    {"sect233r1",
     {"B-233", "wap-wsg-idm-ecid-wtls11", "ansit233r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     116},
    {"sect239k1",
     {"ansit239k1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     119},
    {"sect283k1",
     {"K-283", "ansit283k1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     141},
    {"sect283r1",
     {"B-283", "ansit283r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     141},
    {"sect409k1",
     {"K-409", "ansit409k1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     204},
    {"sect409r1",
     {"B-409", "ansit409r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     204},
    {"sect571k1",
     {"K-571", "ansit571k1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     285},
    {"sect571r1",
     {"B-571", "ansit571r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     285},

    // Category: OSCAA
    // http://gmssl.org/english.html
    {"SM2", {}, CurveForm::Weierstrass, FieldType::Prime, 128},

    // Category: ANSI X9.63
    // ANSI x9.63 example curves.
    {"ansit163k1", {}, CurveForm::Weierstrass, FieldType::Binary, 81},
    {"ansit163r1",
     {"sect163r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     81},
    {"ansit163r2",
     {"sect163r2", "B-163"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     81},
    {"ansit193r1",
     {"sect193r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     96},
    {"ansit193r2",
     {"sect193r2"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     96},
    {"ansit233k1",
     {"sect233k1", "K-233", "wap-wsg-idm-ecid-wtls10"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     116},
    {"ansit233r1",
     {"wap-wsg-idm-ecid-wtls11", "B-233", "sect233r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     116},
    {"ansit239k1",
     {"sect239k1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     119},
    {"ansit283k1",
     {"K-283", "sect283k1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     141},
    {"ansit283r1",
     {"B-283", "sect283r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     141},
    {"ansit409k1",
     {"K-409", "sect409k1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     204},
    {"ansit409r1",
     {"B-409", "sect409r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     204},
    {"ansit571k1",
     {"K-571", "sect571k1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     285},
    {"ansit571r1",
     {"B-571", "sect571r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     285},
    {"ansip160k1", {"secp160k1"}, CurveForm::Weierstrass, FieldType::Prime, 80},
    {"ansip160r1",
     {"secp160r1", "wap-wsg-idm-ecid-wtls7"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     80},
    {"ansip160r2", {"secp160r2"}, CurveForm::Weierstrass, FieldType::Prime, 80},
    {"ansip192k1", {"secp192k1"}, CurveForm::Weierstrass, FieldType::Prime, 96},
    {"ansip224k1",
     {"secp224k1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     112},
    {"ansip224r1",
     {"wap-wsg-idm-ecid-wtls12", "P-224", "secp224r1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     112},
    {"ansip256k1",
     {"secp256k1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     128},
    {"ansip384r1",
     {"secp384r1", "P-384"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     192},
    {"ansip521r1",
     {"secp521r1", "P-521"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     260},

    // Category: ANSI x9.62
    // ANSI x9.62 example curves.
    {"prime192v1",
     {"secp192r1", "P-192"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     96},
    {"prime192v2", {}, CurveForm::Weierstrass, FieldType::Prime, 96},
    {"prime192v3", {}, CurveForm::Weierstrass, FieldType::Prime, 96},
    {"prime239v1", {}, CurveForm::Weierstrass, FieldType::Prime, 119},
    {"prime239v2", {}, CurveForm::Weierstrass, FieldType::Prime, 119},
    {"prime239v3", {}, CurveForm::Weierstrass, FieldType::Prime, 119},
    {"prime256v1",
     {"secp256r1", "P-256"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     128},
    {"c2pnb176w1", {}, CurveForm::Weierstrass, FieldType::Binary, 88},
    {"c2pnb163v1",
     {"wap-wsg-idm-ecid-wtls5"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     81},
    {"c2pnb163v2", {}, CurveForm::Weierstrass, FieldType::Binary, 81},
    {"c2pnb163v3", {}, CurveForm::Weierstrass, FieldType::Binary, 81},
    {"c2pnb208w1", {}, CurveForm::Weierstrass, FieldType::Binary, 104},
    {"c2tnb191v3", {}, CurveForm::Weierstrass, FieldType::Binary, 95},
    {"c2tnb191v2", {}, CurveForm::Weierstrass, FieldType::Binary, 95},
    {"c2tnb191v1", {}, CurveForm::Weierstrass, FieldType::Binary, 95},
    {"c2tnb239v3", {}, CurveForm::Weierstrass, FieldType::Binary, 119},
    {"c2tnb239v2", {}, CurveForm::Weierstrass, FieldType::Binary, 119},
    {"c2tnb239v1", {}, CurveForm::Weierstrass, FieldType::Binary, 119},
    {"c2pnb272w1", {}, CurveForm::Weierstrass, FieldType::Binary, 136},
    {"c2pnb304w1", {}, CurveForm::Weierstrass, FieldType::Binary, 152},
    {"c2pnb368w1", {}, CurveForm::Weierstrass, FieldType::Binary, 184},
    {"c2tnb359v1", {}, CurveForm::Weierstrass, FieldType::Binary, 179},
    {"c2tnb431r1", {}, CurveForm::Weierstrass, FieldType::Binary, 215},
    // A binary-field curve in optimal normal basis
    {"c2onb191v4", {}, CurveForm::Weierstrass, FieldType::Binary, 95},
    // A binary-field curve in optimal normal basis
    {"c2onb191v5", {}, CurveForm::Weierstrass, FieldType::Binary, 95},
    // A binary-field curve in optimal normal basis
    {"c2onb239v4", {}, CurveForm::Weierstrass, FieldType::Binary, 119},
    // A binary-field curve in optimal normal basis
    {"c2onb239v5", {}, CurveForm::Weierstrass, FieldType::Binary, 119},

    // Category: GOST
    // GOST R 34.10-2001: RFC5832, GOST R 34.10-2012: RFC7836
    // RFC5832
    {"gost256", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    // RFC5832
    {"gost512", {}, CurveForm::Weierstrass, FieldType::Prime, 256},
    // RFC7836
    {"id-tc26-gost-3410-12-512-paramSetA",
     {},
     CurveForm::Weierstrass,
     FieldType::Prime,
     256},
    // RFC7836
    {"id-tc26-gost-3410-12-512-paramSetB",
     {},
     CurveForm::Weierstrass,
     FieldType::Prime,
     256},
    // RFC4357
    {"id-GostR3410-2001-CryptoPro-A-ParamSet",
     {},
     CurveForm::Weierstrass,
     FieldType::Prime,
     128},
    // RFC4357
    {"id-GostR3410-2001-CryptoPro-B-ParamSet",
     {},
     CurveForm::Weierstrass,
     FieldType::Prime,
     128},
    // RFC4357
    {"id-GostR3410-2001-CryptoPro-C-ParamSet",
     {},
     CurveForm::Weierstrass,
     FieldType::Prime,
     128},
    // RFC5832
    {"id-tc26-gost-3410-2012-256-paramSetA",
     {},
     CurveForm::TwistedEdwards,
     FieldType::Prime,
     128},
    // RFC5832
    {"id-tc26-gost-3410-2012-512-paramSetC",
     {},
     CurveForm::TwistedEdwards,
     FieldType::Prime,
     256},

    // Category: ANSSI
    // Agence nationale de la sécurité des systèmes d'information: Publication
    // d'un paramétrage de courbe elliptique visant des applications de
    // passeport électronique et de l'administration électronique française. 21
    // November 2011
    {"FRP256v1", {}, CurveForm::Weierstrass, FieldType::Prime, 128},

    // Category: other
    // An assortment of some other curves.
    // Curve from https://eprint.iacr.org/2013/647.pdf
    {"M-221", {}, CurveForm::Montgomery, FieldType::Prime, 110},
    // Curve from https://eprint.iacr.org/2013/647.pdf
    {"M-383", {}, CurveForm::Montgomery, FieldType::Prime, 191},
    // Curve from https://eprint.iacr.org/2013/647.pdf
    {"M-511", {}, CurveForm::Montgomery, FieldType::Prime, 255},
    // Curve from https://eprint.iacr.org/2013/647.pdf
    {"E-222", {}, CurveForm::Edwards, FieldType::Prime, 111},
    // Curve from https://eprint.iacr.org/2013/647.pdf
    {"E-382", {}, CurveForm::Edwards, FieldType::Prime, 191},
    // Curve from https://eprint.iacr.org/2013/647.pdf
    {"E-521", {}, CurveForm::Edwards, FieldType::Prime, 260},
    // Curve from https://cr.yp.to/ecdh.html
    {"Curve25519", {}, CurveForm::Montgomery, FieldType::Prime, 127},
    {"Curve448", {}, CurveForm::Montgomery, FieldType::Prime, 224},
    // Curve from https://github.com/relic-toolkit/relic
    {"Curve22103", {}, CurveForm::Weierstrass, FieldType::Prime, 110},
    // Curve from https://github.com/relic-toolkit/relic
    {"Curve4417", {}, CurveForm::Weierstrass, FieldType::Prime, 113},
    // Curve from https://eprint.iacr.org/2013/325.pdf
    {"Curve1174", {}, CurveForm::Weierstrass, FieldType::Prime, 125},
    // Curve from https://github.com/relic-toolkit/relic
    {"Curve67254", {}, CurveForm::Weierstrass, FieldType::Prime, 191},
    {"Curve383187", {}, CurveForm::Montgomery, FieldType::Prime, 141},
    // Curve from https://ed25519.cr.yp.to
    {"Ed25519", {}, CurveForm::TwistedEdwards, FieldType::Prime, 127},
    // Curve from
    // https://datatracker.ietf.org/doc/html/draft-ietf-lwig-curve-representations-23
    {"Ed448", {}, CurveForm::TwistedEdwards, FieldType::Prime, 224},
    // Curve from https://eprint.iacr.org/2015/625.pdf
    {"Ed448-Goldilocks", {}, CurveForm::TwistedEdwards, FieldType::Prime, 224},
    // Curve from https://cr.yp.to/talks/2013.09.16/slides-djb-20130916-a4.pdf
    {"Curve41417", {}, CurveForm::TwistedEdwards, FieldType::Prime, 207},
    // Curve used in: https://eprint.iacr.org/2010/354.pdf
    {"Fp254BNa", {}, CurveForm::Weierstrass, FieldType::Prime, 127},
    // Curve used in: https://eprint.iacr.org/2010/354.pdf
    {"Fp254n2BNa", {}, CurveForm::Weierstrass, FieldType::Extension, 254},
    // Curve used in
    // https://www.iacr.org/archive/eurocrypt2011/66320047/66320047.pdf
    {"Fp254BNb", {"bn254"}, CurveForm::Weierstrass, FieldType::Prime, 100},
    // Curve described in https://www.iso.org/standard/80241.html
    {"Fp224BN", {}, CurveForm::Weierstrass, FieldType::Prime, 112},
    // Curve described in https://www.iso.org/standard/80241.html
    {"Fp256BN", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    // Curve described in https://www.iso.org/standard/80241.html
    {"Fp384BN", {}, CurveForm::Weierstrass, FieldType::Prime, 192},
    // Curve described in https://www.iso.org/standard/80241.html
    {"Fp512BN", {}, CurveForm::Weierstrass, FieldType::Prime, 256},
    // A prime order curve from MIRACL:
    // https://github.com/miracl/MIRACL/blob/master/docs/miracl-explained/miracl-standard-curves.md.
    // Has no generator specified.
    {"ssc-160", {}, CurveForm::Weierstrass, FieldType::Prime, 80},
    // A prime order curve from MIRACL:
    // https://github.com/miracl/MIRACL/blob/master/docs/miracl-explained/miracl-standard-curves.md.
    // Has no generator specified.
    {"ssc-192", {}, CurveForm::Weierstrass, FieldType::Prime, 96},
    // A prime order curve from MIRACL:
    // https://github.com/miracl/MIRACL/blob/master/docs/miracl-explained/miracl-standard-curves.md.
    // Has no generator specified.
    {"ssc-224", {}, CurveForm::Weierstrass, FieldType::Prime, 112},
    // A prime order curve from MIRACL:
    // https://github.com/miracl/MIRACL/blob/master/docs/miracl-explained/miracl-standard-curves.md.
    // Has no generator specified.
    {"ssc-256", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    // A prime order curve from MIRACL:
    // https://github.com/miracl/MIRACL/blob/master/docs/miracl-explained/miracl-standard-curves.md.
    // Has no generator specified.
    {"ssc-288", {}, CurveForm::Weierstrass, FieldType::Prime, 144},
    // A prime order curve from MIRACL:
    // https://github.com/miracl/MIRACL/blob/master/docs/miracl-explained/miracl-standard-curves.md.
    // Has no generator specified.
    {"ssc-320", {}, CurveForm::Weierstrass, FieldType::Prime, 160},
    // A prime order curve from MIRACL:
    // https://github.com/miracl/MIRACL/blob/master/docs/miracl-explained/miracl-standard-curves.md.
    // Has no generator specified.
    {"ssc-384", {}, CurveForm::Weierstrass, FieldType::Prime, 192},
    // A prime order curve from MIRACL:
    // https://github.com/miracl/MIRACL/blob/master/docs/miracl-explained/miracl-standard-curves.md.
    // Has no generator specified.
    {"ssc-512", {}, CurveForm::Weierstrass, FieldType::Prime, 256},
    // Tweedledum pairing friendly curve from
    // <https://github.com/daira/tweedle>.
    {"Tweedledum", {}, CurveForm::Weierstrass, FieldType::Prime, 127},
    // Tweedledee pairing friendly curve from
    // <https://github.com/daira/tweedle>.
    {"Tweedledee", {}, CurveForm::Weierstrass, FieldType::Prime, 127},
    // JubJub curve from <https://z.cash/technology/jubjub/>.
    {"JubJub", {}, CurveForm::TwistedEdwards, FieldType::Prime, 127},
    // Pallas curve from the [Pasta
    // curves](https://electriccoin.co/blog/the-pasta-curves-for-halo-2-and-beyond/).
    {"Pallas", {}, CurveForm::Weierstrass, FieldType::Prime, 127},
    // Vesta curve from the [Pasta
    // curves](https://electriccoin.co/blog/the-pasta-curves-for-halo-2-and-beyond/).
    {"Vesta", {}, CurveForm::Weierstrass, FieldType::Prime, 127},
    // The Million Dollar Curve
    {"MDC201601", {}, CurveForm::Edwards, FieldType::Prime, 128},
    // BADA55 curve from the https://bada55.cr.yp.to/bada55-20150927.pdf
    {"BADA55-R-256", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    // BADA55 curve from the https://bada55.cr.yp.to/bada55-20150927.pdf
    {"BADA55-VR-224", {}, CurveForm::Weierstrass, FieldType::Prime, 112},
    // BADA55 curve from the https://bada55.cr.yp.to/bada55-20150927.pdf
    {"BADA55-VR-256", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    // BADA55 curve from the https://bada55.cr.yp.to/bada55-20150927.pdf
    {"BADA55-VR-384", {}, CurveForm::Weierstrass, FieldType::Prime, 192},
    // BADA55 curve from the https://bada55.cr.yp.to/bada55-20150927.pdf
    {"BADA55-VPR-224", {}, CurveForm::Weierstrass, FieldType::Prime, 112},
    // BADA55 curve from the https://bada55.cr.yp.to/bada55-20150927.pdf
    {"BADA55-VPR2-224", {}, CurveForm::Weierstrass, FieldType::Prime, 112},

    // Category: NIST
    // RECOMMENDED ELLIPTIC CURVES FOR FEDERAL GOVERNMENT USE  July 1999
    {"P-192",
     {"secp192r1", "prime192v1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     96},
    {"P-224",
     {"secp224r1", "wap-wsg-idm-ecid-wtls12", "ansip224r1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     112},
    {"P-256",
     {"secp256r1", "prime256v1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     128},
    {"P-384",
     {"secp384r1", "ansip384r1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     192},
    {"P-521",
     {"secp521r1", "ansip521r1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     260},
    // Koblitz curve.
    {"K-163", {"sect163k1"}, CurveForm::Weierstrass, FieldType::Binary, 81},
    {"B-163",
     {"sect163r2", "ansit163r2"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     81},
    // Koblitz curve.
    {"K-233",
     {"sect233k1", "wap-wsg-idm-ecid-wtls10", "ansit233k1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     116},
    {"B-233",
     {"sect233r1", "wap-wsg-idm-ecid-wtls11", "ansit233r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     116},
    // Koblitz curve.
    {"K-283",
     {"sect283k1", "ansit283k1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     141},
    {"B-283",
     {"sect283r1", "ansit283r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     141},
    // Koblitz curve.
    {"K-409",
     {"sect409k1", "ansit409k1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     204},
    {"B-409",
     {"sect409r1", "ansit409r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     204},
    // Koblitz curve.
    {"K-571",
     {"sect571k1", "ansit571k1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     285},
    {"B-571",
     {"sect571r1", "ansit571r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     285},

    // Category: Miyaji-Nakabayashi-Takano
    // MNT (Miyaji, Nakabayashi, and Takano curves) example curves from: New
    // explicit conditions of elliptic curve traces for FR-reduction -
    // https://dspace.jaist.ac.jp/dspace/bitstream/10119/4432/1/73-48.pdf.
    {"mnt1", {}, CurveForm::Weierstrass, FieldType::Prime, 85},
    {"mnt2/1", {}, CurveForm::Weierstrass, FieldType::Prime, 79},
    {"mnt2/2", {}, CurveForm::Weierstrass, FieldType::Prime, 79},
    {"mnt3/1", {}, CurveForm::Weierstrass, FieldType::Prime, 80},
    {"mnt3/2", {}, CurveForm::Weierstrass, FieldType::Prime, 80},
    {"mnt3/3", {}, CurveForm::Weierstrass, FieldType::Prime, 80},
    {"mnt4", {}, CurveForm::Weierstrass, FieldType::Prime, 120},
    {"mnt5/1", {}, CurveForm::Weierstrass, FieldType::Prime, 120},
    {"mnt5/2", {}, CurveForm::Weierstrass, FieldType::Prime, 120},
    {"mnt5/3", {}, CurveForm::Weierstrass, FieldType::Prime, 120},

    // Category: Barreto-Lynn-Scott
    // BLS curves. A family of pairing friendly curves, with embedding degree =
    // 12 or 24.
    // Curve from Zexe paper: https://eprint.iacr.org/2018/962, params taken
    // from: https://eips.ethereum.org/EIPS/eip-2539 where they are explicitly
    // listed.
    {"BLS12-377", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    // Curve from https://electriccoin.co/blog/new-snark-curve/. As used in
    // ZCash.
    {"BLS12-381", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    // Curve from https://github.com/relic-toolkit/relic.
    {"BLS12-446", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    // Curve from https://github.com/relic-toolkit/relic.
    {"BLS12-455", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    // Curve from https://github.com/relic-toolkit/relic. Also in

    // https://eprint.iacr.org/2012/232.pdf.
    // Actually, 128 < BLS12-638 < 192
    {"BLS12-638", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    // Curve from https://github.com/relic-toolkit/relic. Also in
    // https://eprint.iacr.org/2012/232.pdf.
    {"BLS24-477", {}, CurveForm::Weierstrass, FieldType::Prime, 192},
    // Curve from
    // https://ethresear.ch/t/introducing-bandersnatch-a-fast-elliptic-curve-built-over-the-bls12-381-scalar-field/9957
    // https://eprint.iacr.org/2021/1152.pdf
    {"Bandersnatch", {}, CurveForm::TwistedEdwards, FieldType::Prime, 128},

    // Category: Barreto-Naehrig
    // BN (Barreto, Naehrig curves) from: A Family of Implementation-Friendly BN
    // Elliptic Curves - <https://eprint.iacr.org/2010/429.pdf>.
    {"bn158", {}, CurveForm::Weierstrass, FieldType::Prime, 70},
    {"bn190", {}, CurveForm::Weierstrass, FieldType::Prime, 80},
    {"bn222", {}, CurveForm::Weierstrass, FieldType::Prime, 80},
    {"bn254", {"Fp254BNb"}, CurveForm::Weierstrass, FieldType::Prime, 100},
    // BN_SNARK, used by Ethereum as the built-in curve on Solidity for Smart
    // Contract, Zcash and etc.
    // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-196.md
    // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md
    // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1108.md
    // Curve named listed by
    // https://docs.google.com/spreadsheets/d/1t6ibmx_BqCxyovP18RfGEUUtKrl2d5MD
    {"bn_snark1", {}, CurveForm::Weierstrass, FieldType::Prime, 100},
    {"bn286", {}, CurveForm::Weierstrass, FieldType::Prime, 100},
    {"bn318", {}, CurveForm::Weierstrass, FieldType::Prime, 100},
    {"bn350", {}, CurveForm::Weierstrass, FieldType::Prime, 100},
    {"bn382", {}, CurveForm::Weierstrass, FieldType::Prime, 100},
    {"bn414", {}, CurveForm::Weierstrass, FieldType::Prime, 100},
    {"bn446", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    {"bn478", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    // Actually, 128 < bn5xx,bn6xx < 192
    {"bn510", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    {"bn542", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    {"bn574", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    {"bn606", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    {"bn638", {}, CurveForm::Weierstrass, FieldType::Prime, 128},

    // Category: WTLS
    // Wireless Application Protocol - Wireless Transport Layer Security
    // (WAP-WTLS) curves:
    // <https://www.wapforum.org/tech/documents/WAP-199-WTLS-20000218-a.pdf>
    {"wap-wsg-idm-ecid-wtls1",
     {},
     CurveForm::Weierstrass,
     FieldType::Binary,
     56},
    {"wap-wsg-idm-ecid-wtls3",
     {"K-163", "sect163k1", "ansit163k1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     81},
    {"wap-wsg-idm-ecid-wtls4",
     {"sect113r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     56},
    {"wap-wsg-idm-ecid-wtls5",
     {"c2pnb163v1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     81},
    {"wap-wsg-idm-ecid-wtls6",
     {"secp112r1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     56},
    {"wap-wsg-idm-ecid-wtls7",
     {"secp160r1", "ansip160r1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     80},
    {"wap-wsg-idm-ecid-wtls8",
     {},
     CurveForm::Weierstrass,
     FieldType::Prime,
     56},
    {"wap-wsg-idm-ecid-wtls9",
     {},
     CurveForm::Weierstrass,
     FieldType::Prime,
     80},
    {"wap-wsg-idm-ecid-wtls10",
     {"sect233k1", "K-233", "ansit233k1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     116},
    {"wap-wsg-idm-ecid-wtls11",
     {"sect233r1", "B-233", "ansit233r1"},
     CurveForm::Weierstrass,
     FieldType::Binary,
     116},
    {"wap-wsg-idm-ecid-wtls12",
     {"secp224r1", "P-224", "ansip224r1"},
     CurveForm::Weierstrass,
     FieldType::Prime,
     112},

    // Category: Oakley
    // Oakley groups from <https://tools.ietf.org/html/rfc2409> and
    // <https://tools.ietf.org/html/rfc5114>
    // Defined in IETF in RFC2409, no generator present.
    {"Oakley Group 3", {}, CurveForm::Weierstrass, FieldType::Binary, 77},
    // Defined in IETF in RFC2409, no generator present.
    {"Oakley Group 4", {}, CurveForm::Weierstrass, FieldType::Binary, 92},
    // Defined in IETF in RFC5114
    {"192-bit Random ECP Group",
     {},
     CurveForm::Weierstrass,
     FieldType::Prime,
     96},
    // Defined in IETF in RFC5114
    {"224-bit Random ECP Group",
     {},
     CurveForm::Weierstrass,
     FieldType::Prime,
     112},
    // Defined in IETF in RFC5114
    {"256-bit Random ECP Group",
     {},
     CurveForm::Weierstrass,
     FieldType::Prime,
     128},
    // Defined in IETF in RFC5114
    {"384-bit Random ECP Group",
     {},
     CurveForm::Weierstrass,
     FieldType::Prime,
     192},
    // Defined in IETF in RFC5114
    {"521-bit Random ECP Group",
     {},
     CurveForm::Weierstrass,
     FieldType::Prime,
     260},

    // Category: NUMS
    // Microsoft Nothing Up My Sleeve (NUMS) curves from:
    // <https://eprint.iacr.org/2014/130> and
    // <https://tools.ietf.org/html/draft-black-numscurves-02>
    {"numsp256d1", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    {"numsp256t1", {}, CurveForm::TwistedEdwards, FieldType::Prime, 128},
    {"numsp384d1", {}, CurveForm::Weierstrass, FieldType::Prime, 192},
    {"numsp384t1", {}, CurveForm::TwistedEdwards, FieldType::Prime, 192},
    {"numsp512d1", {}, CurveForm::Weierstrass, FieldType::Prime, 256},
    {"numsp512t1", {}, CurveForm::TwistedEdwards, FieldType::Prime, 256},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"ed-256-mont", {}, CurveForm::TwistedEdwards, FieldType::Prime, 128},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"ed-254-mont", {}, CurveForm::TwistedEdwards, FieldType::Prime, 127},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"ed-255-mers", {}, CurveForm::TwistedEdwards, FieldType::Prime, 127},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"ed-384-mont", {}, CurveForm::TwistedEdwards, FieldType::Prime, 192},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"ed-382-mont", {}, CurveForm::TwistedEdwards, FieldType::Prime, 191},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"ed-383-mers", {}, CurveForm::TwistedEdwards, FieldType::Prime, 191},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"ed-512-mont", {}, CurveForm::TwistedEdwards, FieldType::Prime, 256},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"ed-510-mont", {}, CurveForm::TwistedEdwards, FieldType::Prime, 255},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"ed-511-mers", {}, CurveForm::TwistedEdwards, FieldType::Prime, 255},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"w-256-mont", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"w-254-mont", {}, CurveForm::Weierstrass, FieldType::Prime, 127},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"w-255-mers", {}, CurveForm::Weierstrass, FieldType::Prime, 127},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"w-384-mont", {}, CurveForm::Weierstrass, FieldType::Prime, 192},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"w-382-mont", {}, CurveForm::Weierstrass, FieldType::Prime, 191},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"w-383-mers", {}, CurveForm::Weierstrass, FieldType::Prime, 191},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"w-512-mont", {}, CurveForm::Weierstrass, FieldType::Prime, 256},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"w-510-mont", {}, CurveForm::Weierstrass, FieldType::Prime, 255},
    // Curve from https://eprint.iacr.org/2014/130.pdf. No generator present.
    {"w-511-mers", {}, CurveForm::Weierstrass, FieldType::Prime, 255},

    // Category: Brainpool
    // ECC Brainpool Standard Curves and Curve Generation v. 1.0  19.10.2005
    {"brainpoolP160r1", {}, CurveForm::Weierstrass, FieldType::Prime, 80},
    {"brainpoolP160t1", {}, CurveForm::Weierstrass, FieldType::Prime, 80},
    {"brainpoolP192r1", {}, CurveForm::Weierstrass, FieldType::Prime, 96},
    {"brainpoolP192t1", {}, CurveForm::Weierstrass, FieldType::Prime, 96},
    {"brainpoolP224r1", {}, CurveForm::Weierstrass, FieldType::Prime, 112},
    {"brainpoolP224t1", {}, CurveForm::Weierstrass, FieldType::Prime, 112},
    {"brainpoolP256r1", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    {"brainpoolP256t1", {}, CurveForm::Weierstrass, FieldType::Prime, 128},
    {"brainpoolP320r1", {}, CurveForm::Weierstrass, FieldType::Prime, 160},
    {"brainpoolP320t1", {}, CurveForm::Weierstrass, FieldType::Prime, 160},
    {"brainpoolP384r1", {}, CurveForm::Weierstrass, FieldType::Prime, 192},
    {"brainpoolP384t1", {}, CurveForm::Weierstrass, FieldType::Prime, 192},
    {"brainpoolP512r1", {}, CurveForm::Weierstrass, FieldType::Prime, 256},
    {"brainpoolP512t1", {}, CurveForm::Weierstrass, FieldType::Prime, 256},
    {"FourQ", {}, CurveForm::TwistedEdwards, FieldType::Extension, 128},
};

CurveName CurveMeta::LowerName() const { return absl::AsciiStrToLower(name); }

bool CurveMeta::IsEquivalent(const CurveMeta& rhs) const {
  return std::tie(form, field_type, secure_bits) ==
         std::tie(rhs.form, rhs.field_type, rhs.secure_bits);
}

std::map<CurveName, CurveMeta> BuildMap() {
  std::map<CurveName, CurveMeta> res;
  auto insert = [&res](const CurveName& name_str, const CurveMeta& meta) {
    // curve names in map will all be lowercase
    auto name = absl::AsciiStrToLower(name_str);
    auto it = res.find(name);
    if (it == res.end()) {
      res.insert({name, meta});
    } else {
      YACL_ENFORCE(it->second.IsEquivalent(meta), "Duplicate curve name {}",
                   name_str);
    }
  };

  for (const auto& curve : kPredefinedCurves) {
    insert(curve.name, curve);
    for (const auto& alias : curve.aliases) {
      insert(alias, curve);
    }
  }
  return res;
}

CurveMeta GetCurveMetaByName(const CurveName& name) {
  static auto curve_map = BuildMap();
  auto name_l = absl::AsciiStrToLower(name);
  auto it = curve_map.find(name_l);
  YACL_ENFORCE(it != curve_map.end(), "Unsupported curve {}", name);
  return it->second;
}

}  // namespace yacl::crypto
